########################################################
##
## ipColorer
## version 1.0
##
## Copyright (c) 2003 by Oleg Volchkov
## e-mail: sumo@proc.ru
##
########################################################
@CLASS
ipColorer

@create[aStr][lTmp]
## Конструктор класса
## aStr          Строка с парсерным кодом.
  $lTmp[$aStr]
  $_str[^lTmp.normalize[]]
  ^_makeLocal[]
  ^_tokenize[]

@load[aFileName]
## Конструктор класса.
## Производит загрузку файла и обработку полученной строки.
## aFileName      Имя файла с парсерным кодом.
  $_file[^file::load[text;$aFileName]]
  $_str[^taint[html][$_file.text]]
  ^_makeLocal[]
  ^_tokenize[]


@getString[]
## Возвращает преобразованную строку.
  $result[$_str]


@getTable[]
## Возвращает преобразованную строку в виде таблицы [построчно].
## Нужно, если хотите вывести с нумерацией строк.
  $result[^_str.split[^#0A][v]]


@_tokenize[][lNum;lComB;lComL]
## Собственно метод, который и раскрашивает код.
## Вызывает локальные методы для разных типов .

  $lUID[^math:uid64[]]

# Помечаем и "выкусываем" коментарии, заменяя их на уникальный идентификатор.
  $lComB[^_str.match[(\^^rem{ .*? })][gx]]
  ^if($lComB){
    $_str[^_str.match[\^^rem{ .*? }][gx]{/%b$lUID%/}]
  }

  $lComL[^_str.match[^^(\# .* )^$][gmx]]
  ^if($lComL){
    $_str[^_str.match[^^\# .* ^$][gmx]{/%l$lUID%/}]
  }

# HTML-теги
  $_str[^_str.match[(</? \w+\s? .*? /? >)][gx]{^_makeHTML[$match.1]}]

# Служебные конструкции
  $_str[^_str.match[^^(@ (?:BASE|USE|CLASS) )^$][gmx]{^_makeService[$match.1]}]
# Описание методов
  $_str[^_str.match[^^(@ [\w\-]+ \[ [\w^;\-]* \] (?:\[ [\w^;\-]* \])? ) (.*)^$][gmx]{^_makeMethodDefine[$match.1;$match.2]}]
# Вызов методов
  $_str[^_str.match[(\^^ [\w\-\.\:]+)][gx]{^_makeMethodCall[$match.1]}]

# Переменные
  $_str[^_str.match[(\^$ \{? [\w\-\.\:]+ \}?)][gx]{^_makeVar[$match.1]}]

# Скобки
  $_str[^_str.match[([\[\]\{\}\(\)]+)][g]{^_makeBrackets[$match.1]}]

# Доделываем коментарии
  ^if($lComB){
     $_str[^_str.match[/%b$lUID%/][g]{^_makeComment[$lComB.1]^lComB.offset(1)}]
  }

  ^if($lComL){
     $_str[^_str.match[/%l$lUID%/][g]{^_makeComment[$lComL.1]^lComL.offset(1)}]
  }

##############################################################
# Обрабатываем конструкции языка...

@_makeComment[aStr]
  ^if(^aStr.left(2) eq "##"){
    $result[<font color="$_colors.inParser"><i>$aStr</i></font>]
  }{
     $result[<font color="$_colors.comment"><i>$aStr</i></font>]
   }

@_makeHTML[aStr]
  $result[<font color="$_colors.html">$aStr</font>]

@_makeService[aStr]
  $result[<font color="$_colors.service">$aStr</font>]

@_makeBrackets[aStr]
  $result[<font color="$_colors.brackets">$aStr</font>]

@_makeVar[aStr]
  ^if($aStr eq "^$result"){
    $result[<font color="$_colors.result">$aStr</font>]
  }{
    $result[<font color="$_colors.var">$aStr</font>]
   }

@_makeMethodDefine[aStr;aAdd]
  $result[<font color="$_colors.methodDefine"><b>$aStr</b></font>^_makeComment[$aAdd]]

@_makeMethodCall[aStr]
## Разделяем вызовы стандартных методов и вызовы пользовательских методов
  ^if($_reservedWords.[^aStr.mid(1)] || ^aStr.left(6) eq "^^MAIN:" || ^aStr.left(6) eq "^^BASE:"){
    $result[<font color="$_colors.reservedWord">$aStr</font>]
  }{
     $result[<font color="$_colors.methodCall">$aStr</font>]
   }


@_makeLocal[]
## Определяем вспомогательные переменные класса

# Цвета
  $_colors[
     $.brackets[#0000AA]
     $.reservedWord[#0000AA]
     $.methodDefine[#990000]
     $.methodCall[#AA0000]
     $.html[#0077DD]
     $.service[#990000]
     $.var[#CC0000]
     $.result[#D27C00]
     $.comment[#888888]
     $.inParser[#555555]
  ]

# Зарезервированные слова
  $_reservedWords[
     $.if(1)
     $.switch(1)
     $.case(1)
     $.for(1)
     $.while(1)
     $.taint(1)
     $.untaint(1)
     $.try(1)
     $.throw(1)
     $.eval(1)
     $.process(1)
     $.cache(1)
     $.use(1)
     $.connect(1)
  ]